        //Only call this inside try/finally which cleans up the lock state!
        private TValue RefreshValueInternal(TKey key)
        {
            _rwlock.EnterUpgradeableReadLock();
            TValue currentValue;
            TValue newValue;
            bool found = _dict.TryGetValue(key, out currentValue);
            try
            {
                newValue = _fillMethod(key, found ? currentValue : _nullValue  );
            }
            // if something really bad is going on, make sure to rethrow rather than handle
            catch (System.OutOfMemoryException) { throw; }
            catch (System.StackOverflowException) { throw; }
            catch (System.ExecutionEngineException) { throw; }
            catch (System.AccessViolationException) { throw; }
            catch (System.AppDomainUnloadedException) { throw; }
            catch (System.BadImageFormatException) { throw; }
            catch (System.InvalidProgramException) { throw; }
            catch (System.Threading.ThreadAbortException) { throw; }
            // If non-serious error occurs in the fill method then remove the key from the table and return 
            // the user's desired "null" value for the specified return type (TValue).
            catch
            {
                _rwlock.EnterWriteLock();
                if (found) _dict.Remove(key);
                return _nullValue;
            }

            if (found)
            {
                //If someone beat us to it, then just return the new value;
                if (currentValue == newValue) return currentValue;
                else
                {
                    _rwlock.EnterWriteLock();
                    _dict[key] = newValue;
                    return newValue;
                }
            }
            else
            {
                _rwlock.EnterWriteLock();
                _dict.Add(key, newValue);
                return newValue;
            }
        }

        public TValue RefreshValue(TKey key)
        {
            try
            {
                return RefreshValueInternal(key);
            }
            finally
            {
                if (_rwlock.IsReadLockHeld) _rwlock.ExitReadLock();
                if (_rwlock.IsWriteLockHeld) _rwlock.ExitWriteLock();
                if (_rwlock.IsUpgradeableReadLockHeld) _rwlock.ExitUpgradeableReadLock();
            }
        }